﻿using SharpBackTestLib.Indicators;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using SharpStockLib.Data;
using System.Reactive.Linq;

namespace SBTLibTest
{
    
    
    /// <summary>
    ///This is a test class for SimpleMovingAverageTest and is intended
    ///to contain all SimpleMovingAverageTest Unit Tests
    ///</summary>
    [TestClass()]
    public class SimpleMovingAverageTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for GetValue
        ///</summary>
        [TestMethod()]
        public void GetValueTest()
        {
            int length = 5;
            SimpleMovingAverage target = new SimpleMovingAverage(length);
            double expected = 3.0; // Should have the following values in buffer : 1, 2, 3, 4, 5. Hence the SMA(5) will be equal to 15/5 = 3.

            // Fake data stream
            IObservable<IData> quotes = Observable.Range(1, length).Select(i =>
                {
                    return new SimpleData(i, i+1, i-1, i, 10, DateTime.Now.AddDays(i));
                });

            int assertions = 0;

            // Using IEnumerable here in order to remain synchronous
            foreach(IData data in quotes.ToEnumerable())
            {
                target.OnNewData(data);

                double? actual = target.GetValue();

                // We will get a null value if the SMA does not have enough data to compute its value
                if (actual != null)
                {
                    // We should get here at least once and only once.
                    Assert.AreEqual(expected, actual);
                    assertions++;
                }
            }

            // Checks the flag that the test was made only once
            if (assertions < 1)
                Assert.Fail("Never tested the values !");
            if(assertions > 1)
                Assert.Fail("Tested the values more than once !");
        }
    }
}
